package com.sneakxy.cloudbase.platform.feign;

import java.io.IOException;
import java.lang.reflect.Type;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.HttpMessageConverterCustomizer;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.session.SessionRepository;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import feign.FeignException;
import feign.Response;

public class FeignResponseDecoder extends SpringDecoder {
	
	private static final Logger LOG = LogManager.getLogger(FeignResponseDecoder.class);

	private SessionRepository<?> sessionRepository;

	public FeignResponseDecoder(
			SessionRepository<?> sessionRepository, 
			ObjectFactory<HttpMessageConverters> messageConverters, 
			ObjectProvider<HttpMessageConverterCustomizer> customizers) {
		super(messageConverters, customizers);
		this.sessionRepository = sessionRepository;
	}

	@Override
	public Object decode(Response response, Type type) throws IOException, FeignException {
        //重新同步SESSION
		this.syncSession();
		return super.decode(response, type);
	}

	protected void syncSession() {
		try {
			if(sessionRepository != null) {
				ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
		                .getRequestAttributes();
		        HttpServletRequest request = attributes.getRequest();
				HttpSession session = request.getSession();
				Object redisSession = sessionRepository.findById(session.getId());
				FieldUtils.writeField(session, "session", redisSession, true);
			}
		} catch (Exception e) {
			LOG.error("同步session缓存数据失败", e);
		}
	}

	public SessionRepository<?> getSessionRepository() {
		return sessionRepository;
	}
	
}
